package com.yc.cloud.admin.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yc.cloud.admin.dto.request.AnswerCreateParam;
import com.yc.cloud.admin.dto.request.AnswerListParam;
import com.yc.cloud.admin.service.AnswerService;
import com.yc.cloud.admin.vo.AnswerVo;
import com.yc.cloud.api.common.MetaHumanRedisConstants;
import com.yc.cloud.api.enums.AnswerShowTypeEnums;
import com.yc.cloud.api.service.TTSCacheService;
import com.yc.cloud.basic.dto.BaseQueryParam;
import com.yc.cloud.entity.Answer;
import com.yc.cloud.mapper.AnswerMapper;
import com.yc.cloud.oss.service.OssFileService;
import lombok.SneakyThrows;
import lombok.val;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 答题库 服务实现类
 * </p>
 *
 * @author Yancy
 * @since 2024-01-31
 */
@Service
public class AnswerServiceImpl extends ServiceImpl<AnswerMapper, Answer> implements AnswerService {

    private final OssFileService ossFileService;
    private final TTSCacheService ttsCacheService;

    public AnswerServiceImpl(OssFileService ossFileService, TTSCacheService ttsCacheService) {
        this.ossFileService = ossFileService;
        this.ttsCacheService = ttsCacheService;
    }

    @Override
    public IPage<AnswerVo> list(AnswerListParam param, BaseQueryParam queryParam) {
        val query = new QueryWrapper<Answer>();
        IPage<Answer> page;
        if (StrUtil.isNotEmpty(param.getQuestionNo())) {
            query.eq(Answer.QUESTION_NO, param.getQuestionNo());
        }
        //排序
        if (StrUtil.isNotEmpty(queryParam.getSortBy())) {
            if (BaseQueryParam.ORDER_DESC.equals(queryParam.getOrder())) {
                query.orderByDesc(queryParam.getSortBy());
            } else if (BaseQueryParam.ORDER_ASC.equals(queryParam.getOrder())) {
                query.orderByAsc(queryParam.getSortBy());
            }
        }
        //模糊查询,问题编号
        if (StrUtil.isNotEmpty(queryParam.getKeyword())) {
            query.and(queryWrapper -> {
                queryWrapper.like(Answer.QUESTION_NO, queryParam.getKeyword());
            });
        }
        //分页
        if (queryParam.getPage()) {
            page = new Page<>(queryParam.getPageNum(), queryParam.getPageSize(), true);
        } else {
            page = new Page<>(queryParam.getPageNum(), baseMapper.selectCount(query), true);
        }
//        val result = baseMapper.selectPage(page, query);
        val result = baseMapper.listPage(page, query);
        val newResult = result.convert(this::convertVo);
        // 对结果进行排序
        List<AnswerVo> sortedList = newResult.getRecords().stream()
                .sorted(Comparator.comparingInt(AnswerVo::getStep))
                .collect(Collectors.toList());
        newResult.setRecords(sortedList);
        return newResult;
    }

    @Override
    public Answer create(AnswerCreateParam param) {
        val answer = new Answer();
        BeanUtils.copyProperties(param, answer);
        val saveFlag = save(answer);
        return saveFlag ? answer : null;
    }

    @Override
    public Answer get(Long id) {
        return getById(id);
    }

    @Override
    public boolean delete(Long id) {
        val flag = removeById(id);
        if (flag) {
            deleteTTSCache(id);
        }
        return flag;
    }

    @Override
    public boolean deleteByQuestionNo(String questionNo) {
        val result = baseMapper.delete(new QueryWrapper<Answer>().eq(Answer.QUESTION_NO, questionNo));
        return result > 0;
    }

    @Override
    public Answer update(Long id, Answer param) {
        val answer = new Answer();
        BeanUtils.copyProperties(param, answer);
        answer.setId(id);
        val updateFlag = updateById(answer);
        if (updateFlag) {
            deleteTTSCache(id);
        }
        return updateFlag ? answer : null;
    }


    @SneakyThrows
    @Override
    public <T> AnswerVo convertVo(T answer) {
        if (answer == null) {
            return null;
        }
        val vo = new AnswerVo();
        BeanUtils.copyProperties(answer, vo);
        //不是文本则需要进行数据转化
        if (!AnswerShowTypeEnums.TEXT.getCode().equals(vo.getShowType())) {
            String content = (String) BeanUtils.getPropertyDescriptor(answer.getClass(), "content").getReadMethod().invoke(answer);
            //val content = answer.getContent();
            if (StrUtil.isNotEmpty(content)) {
                val contentArray = content.split(",");
                val fileIds = Arrays.asList(contentArray);
                val ossFileList = ossFileService.listByFileIds(fileIds);
                if (CollUtil.isNotEmpty(ossFileList)) {
                    val ossFileListVo = ossFileList.stream().map(ossFileService::convertVo).collect(Collectors.toList());
                    vo.setOssFileList(ossFileListVo);
                }
            }
        }
        return vo;
    }


    @Override
    public List<AnswerVo> convertVo(List<Answer> AnswerList) {
        if (CollUtil.isNotEmpty(AnswerList)) {
            return AnswerList.stream().map(this::convertVo).collect(Collectors.toList());
        }
        return new ArrayList<>();
    }

    private void deleteTTSCache(Long id) {
        val femaleKey = MetaHumanRedisConstants.ANSWER_TSS_KEY_FEMALE.replace(MetaHumanRedisConstants.ANSWER_ID, String.valueOf(id));
        val manKey = MetaHumanRedisConstants.ANSWER_TSS_KEY_MAN.replace(MetaHumanRedisConstants.ANSWER_ID, String.valueOf(id));
        ttsCacheService.delByKey(femaleKey);
        ttsCacheService.delByKey(manKey);
    }

}
